package com.smart.common.config.jackson;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

/**
 * Jackson配置类
 *
 * @author Administrator
 * @date 2022/09/08
 */
@Configuration
public class JacksonConfiguration {


    @Bean
    public ObjectMapper getJacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {


        //localDateTime格式化
        String datePattern = "yyyy-MM-dd";
        String dateTimePattern = "yyyy-MM-dd HH:mm:ss";
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        //日期时间序列化
        LocalDateTimeDeserializer dateTimeDeserializer = new LocalDateTimeDeserializer( DateTimeFormatter.ofPattern( dateTimePattern ) );
        LocalDateTimeSerializer dateTimeSerializer = new LocalDateTimeSerializer( DateTimeFormatter.ofPattern( dateTimePattern ) );
        javaTimeModule.addDeserializer( LocalDateTime.class, dateTimeDeserializer );
        javaTimeModule.addSerializer( LocalDateTime.class, dateTimeSerializer );

        //日期格式序列化
        LocalDateSerializer dateSerializer = new LocalDateSerializer( DateTimeFormatter.ofPattern( datePattern ) );
        LocalDateDeserializer dateDeserializer = new LocalDateDeserializer( DateTimeFormatter.ofPattern( datePattern ) );
        javaTimeModule.addDeserializer( LocalDate.class, dateDeserializer );
        javaTimeModule.addSerializer( LocalDate.class, dateSerializer );

        //序列换成json时,将所有的long变成string.因为js中得数字类型不能包含所有的java long值，超过16位后会出现精度丢失
        SimpleModule longModule = new SimpleModule();
        longModule.addSerializer( Long.class, ToStringSerializer.instance );
        longModule.addSerializer( Long.TYPE, ToStringSerializer.instance );

        ObjectMapper build = builder.createXmlMapper( false )
                .featuresToDisable( SerializationFeature.WRITE_DATES_AS_TIMESTAMPS )
                .modules( javaTimeModule, longModule )
                .build();
        //反序列化的时候如果多了其他属性,不抛出异常
        build.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
        //日期格式处理
        build.setDateFormat( new SimpleDateFormat( dateTimePattern ) );
        //返回的JSON对象空值过滤 non_null 忽略控制  always =全部显示
        build.setDefaultPropertyInclusion( JsonInclude.Include.ALWAYS );
        build.setTimeZone( TimeZone.getTimeZone( "Asia/Shanghai" ) );
        return build;
    }


}
